/*
 * Contexto.h
 *
 *  Created on: 07/06/2010
 *      Author: administrador
 */

#ifndef CONTEXTO_H_
#define CONTEXTO_H_
#include <string>
#include <iostream>
#include <vector>
#include "Distribucion.h"
#include "Emisor.h"
#include "../Arbol/Elemento.h"
#include "Compresor.h"

using namespace std;

class Contexto {

private:

	string clave;

	vector<Distribucion*> caracteres;

	int cantidadCaracteres;

	typeFrecuencias totalFrecuencias;

	/* Retorna la posicion del caracter en el vector caracteres
	 * Si no encuentra el caracter, retorna -1 */
	int getIndice(typeCaracterChar caracter);

	/* Ordena en forma ascendente el vector caracteres */
	void ordenarCaracteres();

	/* Retorna la frecuencia de caracter en el contexto */
	typeFrecuencias getFrecuencia(typeCaracterChar caraceter);

	/* Retorna la suma de las frecuencias de los caracteres anteriores a caracter */
	typeFrecuencias getFrecuenciaAcumulada(typeCaracterChar caraceter);

	/* Retorna la distribucion del caracter pasado por parametro.
	 * Si no se encuentra, retorna la distribucion del caracter ESCAPE */
	Distribucion* obtenerDistribucion(typeCaracterChar caracter);

	/* Si el caracter existe en este contexto, le sumo frecuencia; sino, lo agrego
	 * y le sumo frecuencia a ESCAPE */
	void actualizar(typeCaracterChar caracter);

public:

	typeFrecuencias getTotalFrecuencias();

	/* Retorna la distribucion del caracter pasado por parametro en este contexto
	 * Si no encuentra el caracter en este contexto, retorna NULL */
	Distribucion* getDistribucion(typeCaracterChar caracter);

	/* Agrega una nueva distribucion al contexto */
	void agregarDistribucion(typeCaracterChar caracter);

	Contexto(string clave);

	Contexto();

	virtual ~Contexto();

	string getClave();

	/* Emite la distribucion que corresponda para caracter en este contexto
	 * Si se emite ESCAPE retorna TRUE; si se emite el caracter, FALSE */
	virtual bool emitir(typeCaracterAscii caracter);

	virtual typeCaracterAscii emitirDescomprimido ();

	Elemento* serializar();

	void hidratar(Elemento *elementoContexto);

	/*
	 * Aumenta la frecuencia de la distribucion en caso que exista y sino la agrega */
	void acumularCaracter(typeCaracterChar caracter);

	/*
	 * Retorna la cantidad de caracteres del contexto, o sea el Orden del mismo */
	int getOrden();

};

#endif /* CONTEXTO_H_ */
